﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using HandyControl.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZGRemote.Server.Core.Handler;
using ZGRemote.Server.Core.Models;
using ZGRemote.Server.UI.Resources;

namespace ZGRemote.Server.UI.ViewModels
{
    partial class RemoteFileExplorerViewModel : RemoteViewModelBase
    {
        [ObservableProperty]
        private string[] drives;

        [ObservableProperty]
        private string driveCurrentSelect;

        [ObservableProperty]
        private List<FileModel> fileList;

        private string currentPath;

        [ObservableProperty]
        private string path;

        private bool isGoBack;
        private Stack<string> goBackPathStack = new Stack<string>();

        private Stack<string> goFowardPathStack = new Stack<string>();

        public RemoteFileExplorerViewModel(User user) : base(user) 
        {
            fileList = new List<FileModel>();
            drives = RemoteFileExplorerHandler.GetDrives(user.UserContext);
            path = drives[0];
            driveCurrentSelect = drives[0];
            currentPath = drives[0];
            header = $"{Core.Properties.Resources.RemoteFileExplorer}@{user.IP}:{user.Port}";
            GetFileList().ConfigureAwait(false);
        }

        private bool CanGoBack => goBackPathStack.Count > 0;

        [RelayCommand(CanExecute = nameof(CanGoBack))]
        private async Task GoBackAsync()
        {
            string temp = currentPath;
            Path = goBackPathStack.Pop();
            GoBackCommand.NotifyCanExecuteChanged();
            isGoBack = true;
            await GetFileList();
            isGoBack = false;
            goFowardPathStack.Push(temp);
            GoFowardCommand.NotifyCanExecuteChanged();
        }

        private bool CanGoFoward => goFowardPathStack.Count > 0;

        [RelayCommand(CanExecute = nameof(CanGoFoward))]
        private async Task GoFoward()
        {
            Path = goFowardPathStack.Pop();
            GoFowardCommand.NotifyCanExecuteChanged();
            await GetFileList();
        }

        [RelayCommand]
        private async Task GoHome()
        {
            Path = DriveCurrentSelect;
            await GetFileList();
        }

        [RelayCommand]
        private async Task RefreshFileList()
        {
            Path = currentPath;
            await GetFileList();
        }

        [RelayCommand]
        private async Task PathBoxEnterDown()
        {
            await GetFileList();
        }

        [RelayCommand]
        private async Task DriveChanged()
        {
            // 切换页面时会触发DriveChanged, 如果这时候DriveChanged引发异常可能会导致页面永久停留在UI上或者直接崩溃
            if (IsActivise)
            {
                Path = DriveCurrentSelect;
                await GetFileList();
            }
            
        }

        [RelayCommand]
        private async Task ListViewDoubleClick(FileModel file)
        {
            if (file.Type == FileType.Folder)
            {
                Path = System.IO.Path.Combine(currentPath, file.Name);
                await GetFileList();
            }
        }

        private async Task<bool> GetFileList()
        {
            if (string.IsNullOrEmpty(Path))
            {
                Growl.Error(Core.Properties.Resources.PathIsNull);
                return false;
            }
            FileList = (await RemoteFileExplorerHandler.GetFilesAsync(User!.UserContext, Path)).ToList();
            if (currentPath != Path && isGoBack != true)
            {
                goBackPathStack.Push(currentPath);
                GoBackCommand.NotifyCanExecuteChanged();
            }
            currentPath = Path;

            return true;
        }
    }
}
